#!/usr/bin/env python3
"""
HTTP协议处理器
"""
import asyncio
import base64
import random
import uuid
from datetime import datetime, timezone
from typing import Optional

from .base_handler import ProtocolHandler
from .logger import op_logger
from multihoneypot.attacklogger import attack_logger, AttackType, ProtocolType


class HTTPHandler(ProtocolHandler):
    """
    HTTP协议处理器，模拟简单的HTTP服务端
    """

    # 多个响应页面内容，增加随机性
    RESPONSE_BODIES = [
        b"<!DOCTYPE html>\n<html>\n<head>\n<title>Welcome to nginx!</title>\n<style>\n    body {\n        width: 35em;\n        margin: 0 auto;\n        font-family: Tahoma, Verdana, Arial, sans-serif;\n    }\n</style>\n</head>\n<body>\n<h1>Welcome to nginx!</h1>\n<p>If you see this page, the nginx web server is successfully installed and\nworking. Further configuration is required.</p>\n\n<p>For online documentation and support please refer to\n<a href=\"http://nginx.org/\">nginx.org</a>.<br/>\nCommercial support is available at\n<a href=\"http://nginx.com/\">nginx.com</a>.</p>\n\n<p><em>Thank you for using nginx.</em></p>\n</body>\n</html>\n",
        b"<!DOCTYPE html>\n<html>\n<head>\n<title>Test Page for nginx</title>\n<style>\n    body {\n        width: 35em;\n        margin: 0 auto;\n        font-family: Tahoma, Verdana, Arial, sans-serif;\n    }\n</style>\n</head>\n<body>\n<h1>Welcome to nginx!</h1>\n<p>This is a test page used to test the correct operation of the nginx.</p>\n</body>\n</html>\n",
        b"<!DOCTYPE html>\n<html>\n<head>\n<title>Default Web Page</title>\n<style>\n    body {\n        width: 35em;\n        margin: 0 auto;\n        font-family: Tahoma, Verdana, Arial, sans-serif;\n    }\n</style>\n</head>\n<body>\n<h1>Default Web Page</h1>\n<p>This is the default web page for this server.</p>\n<p>The web server software is running but no content has been added, yet.</p>\n</body>\n</html>\n"
    ]

    # 真实的nginx版本号
    NGINX_VERSIONS = [
        "nginx/1.18.0",
        "nginx/1.20.1",
        "nginx/1.21.6",
        "nginx/1.22.1",
        "nginx/1.23.3",
        "nginx/1.24.0"
    ]

    # 登录页面模板
    LOGIN_PAGE = b"""<!DOCTYPE html>
<html>
<head>
    <title>Login</title>
    <style>
        body { font-family: Arial, sans-serif; background-color: #f5f5f5; }
        .login-container { width: 300px; margin: 100px auto; padding: 20px; background-color: white; border-radius: 5px; box-shadow: 0 0 10px rgba(0,0,0,0.1); }
        h2 { text-align: center; color: #333; }
        input { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #ddd; border-radius: 3px; box-sizing: border-box; }
        button { width: 100%; padding: 10px; background-color: #007cba; color: white; border: none; border-radius: 3px; cursor: pointer; }
        button:hover { background-color: #005a87; }
    </style>
</head>
<body>
    <div class="login-container">
        <h2>Admin Login</h2>
        <form method="POST">
            <input type="text" name="username" placeholder="Username" required>
            <input type="password" name="password" placeholder="Password" required>
            <button type="submit">Login</button>
        </form>
    </div>
</body>
</html>"""

    # 登录API的JSON响应
    LOGIN_JSON_RESPONSES = [
        b'{"success": false, "message": "Invalid credentials"}',
        b'{"success": false, "message": "Authentication failed"}',
        b'{"error": {"code": "INVALID_CREDENTIALS", "message": "The provided credentials are incorrect"}}',
        b'{"error": "Unauthorized", "message": "Login failed. Please check your username and password."}'
    ]

    # phpMyAdmin页面模板
    PHPMYADMIN_PAGE = b"""<!DOCTYPE html>
<html lang="en">
<head>
    <title>phpMyAdmin</title>
    <meta charset="utf-8">
    <style>
        body { font-family: sans-serif; background-color: #f5f5f5; margin: 0; padding: 0; }
        .container { max-width: 500px; margin: 100px auto; background: white; padding: 30px; border-radius: 5px; box-shadow: 0 0 10px rgba(0,0,0,0.1); }
        h1 { text-align: center; color: #666; }
        .form-group { margin-bottom: 20px; }
        label { display: block; margin-bottom: 5px; }
        input { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 3px; box-sizing: border-box; }
        button { width: 100%; padding: 10px; background-color: #ffd600; color: black; border: none; border-radius: 3px; cursor: pointer; font-weight: bold; }
        button:hover { background-color: #e6c000; }
    </style>
</head>
<body>
    <div class="container">
        <h1>Welcome to phpMyAdmin</h1>
        <form method="post" action="index.php">
            <div class="form-group">
                <label for="server">Server:</label>
                <input type="text" id="server" name="server" value="localhost" required>
            </div>
            <div class="form-group">
                <label for="username">Username:</label>
                <input type="text" id="username" name="username" required>
            </div>
            <div class="form-group">
                <label for="password">Password:</label>
                <input type="password" id="password" name="password" required>
            </div>
            <button type="submit">Go</button>
        </form>
    </div>
</body>
</html>"""

    # Admin面板页面模板
    ADMIN_PAGE = b"""<!DOCTYPE html>
<html>
<head>
    <title>Admin Panel</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 0; padding: 0; background-color: #f1f1f1; }
        .header { background-color: #333; color: white; padding: 15px; }
        .login-form { width: 300px; margin: 100px auto; background: white; padding: 30px; border-radius: 5px; box-shadow: 0 0 10px rgba(0,0,0,0.1); }
        .form-group { margin-bottom: 20px; }
        label { display: block; margin-bottom: 5px; }
        input { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 3px; box-sizing: border-box; }
        button { width: 100%; padding: 10px; background-color: #4CAF50; color: white; border: none; border-radius: 3px; cursor: pointer; }
        button:hover { background-color: #45a049; }
    </style>
</head>
<body>
    <div class="header">
        <h2>Admin Panel</h2>
    </div>
    <div class="login-form">
        <h3>Login</h3>
        <form method="POST">
            <div class="form-group">
                <label>Username:</label>
                <input type="text" name="username" required>
            </div>
            <div class="form-group">
                <label>Password:</label>
                <input type="password" name="password" required>
            </div>
            <button type="submit">Login</button>
        </form>
    </div>
</body>
</html>"""

    # API数据示例
    API_DATA = [
        b'{"users": [{"id": 1, "name": "John Doe", "email": "john@example.com"}, {"id": 2, "name": "Jane Smith", "email": "jane@example.com"}], "total": 2}',
        b'{"products": [{"id": 1, "name": "Product 1", "price": 29.99}, {"id": 2, "name": "Product 2", "price": 39.99}], "total": 2}',
        b'{"orders": [{"id": 1001, "customer": "John Doe", "amount": 99.99, "status": "shipped"}, {"id": 1002, "customer": "Jane Smith", "amount": 149.99, "status": "pending"}], "total": 2}'
    ]

    # 静态资源内容
    STATIC_CONTENTS = {
        "/favicon.ico": (b"\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00", "image/x-icon"),
        "/robots.txt": (b"User-agent: *\nDisallow: /admin/\nDisallow: /private/\n", "text/plain"),
        "/sitemap.xml": (
            b"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n<url>\n<loc>http://localhost/</loc>\n</url>\n</urlset>",
            "application/xml"),
    }

    def __init__(self, host, port, log_file):
        """
        初始化HTTP处理器

        Args:
            host (str): 监听主机地址
            port (int): 监听端口
            log_file (str): 日志文件路径
        """
        super().__init__("http", host, port, log_file)
        # 生成带hash的动态路径
        self.dynamic_paths = self._generate_dynamic_paths()

    def _generate_dynamic_paths(self):
        """生成动态路径"""
        paths = {}
        for i in range(10):
            path = f"/{uuid.uuid4().hex}.php"
            content = b"<?php\n// This is a simulated PHP file\nphpinfo();\n?>"
            paths[path] = (content, "text/plain")
        return paths

    async def start(self):
        """
        启动HTTP服务器
        """
        self._server = await asyncio.start_server(self._handle, host=self.host, port=self.port)
        addrs = ", ".join(str(sock.getsockname()) for sock in self._server.sockets)
        op_logger.info("HTTP监听于 %s", addrs)
        return asyncio.create_task(self._server.serve_forever())

    def _generate_session_id(self):
        """生成随机会话ID"""
        return ''.join(random.choices('0123456789abcdef', k=32))

    def _generate_etag(self):
        """生成ETag"""
        return '"' + ''.join(random.choices('0123456789abcdef', k=16)) + '"'

    async def _simulate_network_delay(self, writer: asyncio.StreamWriter, content_length: int):
        """
        模拟网络延迟

        Args:
            writer (asyncio.StreamWriter): 流写入器
            content_length (int): 内容长度
        """
        # 根据内容长度模拟网络延迟
        delay = min(content_length / 10000, 1.0)  # 最大1秒延迟
        if delay > 0.01:
            await asyncio.sleep(delay * 0.1)

    async def _handle(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter):
        """
        处理HTTP客户端请求

        Args:
            reader (asyncio.StreamReader): 用于从连接中读取数据的流读取器
            writer (asyncio.StreamWriter): 用于向连接写入数据的流写入器
        """
        peer = writer.get_extra_info("peername") or ("unknown", 0)
        session_id = str(uuid.uuid4())
        start_ts = datetime.now(timezone.utc)
        try:
            raw = await reader.read(64 * 1024)  # 读取最多64KB的头部和内容
            text = raw.decode(errors="ignore")

            # 解析请求
            request_lines = text.split('\n')
            if not request_lines:
                writer.close()
                return

            request_line = request_lines[0].strip()
            headers = {}
            for line in request_lines[1:]:
                if ':' in line:
                    key, value = line.split(':', 1)
                    headers[key.strip().lower()] = value.strip()

            parts = request_line.split()
            if len(parts) < 3:
                writer.close()
                return

            method, path, version = parts[0], parts[1], parts[2]

            # 记录HTTP请求到攻击日志
            attack_logger.log_command_execution(
                source_ip=peer[0],
                destination_port=self.port,
                protocol=ProtocolType.HTTP,
                command=f"{method} {path} {version}",
                command_type="http_request"
            )

            # 检查是否为可疑路径
            if any(pattern in path.lower() for pattern in ['manager', 'python', '.env', 'flask', 'django']):
                body = b'<!DOCTYPE html>\n<html>\n<head>\n<title>404 Not Found</title>\n</head>\n<body>\n<center><h1>404 Not Found</h1></center>\n<hr><center>nginx</center>\n</body>\n</html>\n'
                server_header = random.choice(self.NGINX_VERSIONS)
                resp = b"HTTP/1.1 404 Not Found\r\nServer: %s\r\nDate: %s\r\nContent-Type: text/html\r\nContent-Length: %d\r\nConnection: close\r\n\r\n%s" % (
                    server_header.encode(),
                    datetime.now().strftime('%a, %d %b %Y %H:%M:%S GMT').encode(),
                    len(body),
                    body
                )
                writer.write(resp)
                await writer.drain()
                return

            # 处理phpMyAdmin页面请求
            if path.startswith("/phpmyadmin"):
                if path == "/phpmyadmin" or path == "/phpmyadmin/":
                    if method == "GET":
                        body = self.PHPMYADMIN_PAGE
                        content_type = "text/html"
                    elif method == "POST":
                        # 记录登录尝试
                        post_data = f"<PHPMyAdmin login attempt with {headers.get('content-length', 'unknown')} bytes of data>"
                        op_logger.info("phpMyAdmin login attempt from %s: %s", peer[0], post_data)

                        # 记录认证尝试到攻击日志
                        attack_logger.log_auth_attempt(
                            source_ip=peer[0],
                            destination_port=self.port,
                            protocol=ProtocolType.HTTP,
                            username="phpmyadmin_user",
                            password="<captured>"
                        )

                        # 返回登录失败页面
                        body = b"""<!DOCTYPE html>
<html>
<head>
    <title>phpMyAdmin</title>
    <style>
        body { font-family: sans-serif; background-color: #f5f5f5; }
        .error { width: 500px; margin: 100px auto; background: white; padding: 30px; border-radius: 5px; box-shadow: 0 0 10px rgba(0,0,0,0.1); border-left: 5px solid #f44336; }
        .error h2 { color: #f44336; }
        .back-link { display: block; text-align: center; margin-top: 20px; color: #2196F3; text-decoration: none; }
    </style>
</head>
<body>
    <div class="error">
        <h2>Login failed</h2>
        <p>Invalid credentials. Please try again.</p>
        <a href="index.php" class="back-link">Back to login</a>
    </div>
</body>
</html>"""
                        content_type = "text/html"
                    else:
                        body = b'{"error": "Method not allowed"}'
                        content_type = "application/json"

                    server_header = random.choice(self.NGINX_VERSIONS)
                    resp = b"HTTP/1.1 200 OK\r\nServer: %s\r\nDate: %s\r\nContent-Type: %s\r\nContent-Length: %d\r\nConnection: close\r\n\r\n%s" % (
                        server_header.encode(),
                        datetime.now().strftime('%a, %d %b %Y %H:%M:%S GMT').encode(),
                        content_type.encode(),
                        len(body),
                        body
                    )
                    await self._simulate_network_delay(writer, len(body))
                    writer.write(resp)
                    await writer.drain()
                    return
                else:
                    # phpMyAdmin子路径返回404
                    body = b'<!DOCTYPE html>\n<html>\n<head>\n<title>404 Not Found</title>\n</head>\n<body>\n<center><h1>404 Not Found</h1></center>\n<hr><center>nginx</center>\n</body>\n</html>\n'
                    server_header = random.choice(self.NGINX_VERSIONS)
                    resp = b"HTTP/1.1 404 Not Found\r\nServer: %s\r\nDate: %s\r\nContent-Type: text/html\r\nContent-Length: %d\r\nConnection: close\r\n\r\n%s" % (
                        server_header.encode(),
                        datetime.now().strftime('%a, %d %b %Y %H:%M:%S GMT').encode(),
                        len(body),
                        body
                    )
                    writer.write(resp)
                    await writer.drain()
                    return

            # 处理Admin面板请求
            if path.startswith("/admin"):
                if path == "/admin" or path == "/admin/":
                    if method == "GET":
                        body = self.ADMIN_PAGE
                        content_type = "text/html"
                    elif method == "POST":
                        # 记录登录尝试
                        post_data = f"<Admin panel login attempt with {headers.get('content-length', 'unknown')} bytes of data>"
                        op_logger.info("Admin panel login attempt from %s: %s", peer[0], post_data)

                        # 记录认证尝试到攻击日志
                        attack_logger.log_auth_attempt(
                            source_ip=peer[0],
                            destination_port=self.port,
                            protocol=ProtocolType.HTTP,
                            username="admin_user",
                            password="<captured>"
                        )

                        # 返回登录失败页面
                        body = b"""<!DOCTYPE html>
<html>
<head>
    <title>Admin Panel</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 0; padding: 0; background-color: #f1f1f1; }
        .header { background-color: #333; color: white; padding: 15px; }
        .error { width: 300px; margin: 100px auto; background: white; padding: 30px; border-radius: 5px; box-shadow: 0 0 10px rgba(0,0,0,0.1); border-left: 5px solid #f44336; }
        .error h3 { color: #f44336; margin-top: 0; }
        .back-link { display: block; text-align: center; margin-top: 20px; color: #2196F3; text-decoration: none; }
    </style>
</head>
<body>
    <div class="header">
        <h2>Admin Panel</h2>
    </div>
    <div class="error">
        <h3>Login Failed</h3>
        <p>Invalid username or password.</p>
        <a href="/" class="back-link">Back to login</a>
    </div>
</body>
</html>"""
                        content_type = "text/html"
                    else:
                        body = b'{"error": "Method not allowed"}'
                        content_type = "application/json"

                    server_header = random.choice(self.NGINX_VERSIONS)
                    resp = b"HTTP/1.1 200 OK\r\nServer: %s\r\nDate: %s\r\nContent-Type: %s\r\nContent-Length: %d\r\nConnection: close\r\n\r\n%s" % (
                        server_header.encode(),
                        datetime.now().strftime('%a, %d %b %Y %H:%M:%S GMT').encode(),
                        content_type.encode(),
                        len(body),
                        body
                    )
                    await self._simulate_network_delay(writer, len(body))
                    writer.write(resp)
                    await writer.drain()
                    return
                else:
                    # Admin子路径返回404
                    body = b'<!DOCTYPE html>\n<html>\n<head>\n<title>404 Not Found</title>\n</head>\n<body>\n<center><h1>404 Not Found</h1></center>\n<hr><center>nginx</center>\n</body>\n</html>\n'
                    server_header = random.choice(self.NGINX_VERSIONS)
                    resp = b"HTTP/1.1 404 Not Found\r\nServer: %s\r\nDate: %s\r\nContent-Type: text/html\r\nContent-Length: %d\r\nConnection: close\r\n\r\n%s" % (
                        server_header.encode(),
                        datetime.now().strftime('%a, %d %b %Y %H:%M:%S GMT').encode(),
                        len(body),
                        body
                    )
                    writer.write(resp)
                    await writer.drain()
                    return

            # 处理API请求
            if path.startswith("/api/"):
                if method == "GET":
                    body = random.choice(self.API_DATA)
                    content_type = "application/json"
                else:
                    body = b'{"error": "Method not allowed"}'
                    content_type = "application/json"

                server_header = random.choice(self.NGINX_VERSIONS)
                resp = b"HTTP/1.1 200 OK\r\nServer: %s\r\nDate: %s\r\nContent-Type: %s\r\nContent-Length: %d\r\nConnection: close\r\n\r\n%s" % (
                    server_header.encode(),
                    datetime.now().strftime('%a, %d %b %Y %H:%M:%S GMT').encode(),
                    content_type.encode(),
                    len(body),
                    body
                )
                await self._simulate_network_delay(writer, len(body))
                writer.write(resp)
                await writer.drain()
                return

            # 处理登录页面请求
            if path == "/login" and method == "GET":
                # 检查Accept头以决定返回HTML还是JSON
                accept_header = headers.get('accept', '')
                if 'application/json' in accept_header and 'text/html' not in accept_header:
                    # 返回JSON格式的登录页面信息
                    body = b'{"login_url": "/login", "method": "POST", "fields": ["username", "password"]}'
                    content_type = "application/json"
                else:
                    # 返回HTML登录页面
                    body = self.LOGIN_PAGE
                    content_type = "text/html"

                server_header = random.choice(self.NGINX_VERSIONS)
                resp = b"HTTP/1.1 200 OK\r\nServer: %s\r\nDate: %s\r\nContent-Type: %s\r\nContent-Length: %d\r\nConnection: close\r\n\r\n%s" % (
                    server_header.encode(),
                    datetime.now().strftime('%a, %d %b %Y %H:%M:%S GMT').encode(),
                    content_type.encode(),
                    len(body),
                    body
                )
                await self._simulate_network_delay(writer, len(body))
                writer.write(resp)
                await writer.drain()
                return

            # 处理登录表单提交
            if path == "/login" and method == "POST":
                # 检查Content-Type以决定如何处理请求
                content_type_header = headers.get('content-type', '').lower()

                # 记录提交的登录凭据
                post_data = b""
                content_length = 0
                if "content-length" in headers:
                    try:
                        content_length = int(headers["content-length"])
                    except ValueError:
                        pass

                # 简化处理，实际应该读取body内容
                post_data = f"<{content_length} bytes of POST data>".encode()

                # 记录认证尝试到攻击日志
                attack_logger.log_auth_attempt(
                    source_ip=peer[0],
                    destination_port=self.port,
                    protocol=ProtocolType.HTTP,
                    username="web_user",
                    password="<captured>"
                )

                # 根据请求的Accept头决定返回什么类型的数据
                accept_header = headers.get('accept', '')
                if 'application/json' in accept_header and 'text/html' not in accept_header:
                    # 返回JSON格式的错误响应
                    body = random.choice(self.LOGIN_JSON_RESPONSES)
                    content_type = "application/json"
                    status_line = "HTTP/1.1 401 Unauthorized"
                else:
                    # 返回HTML格式的错误响应
                    body = b'<!DOCTYPE html>\n<html>\n<head>\n<title>Login Failed</title>\n</head>\n<body>\n<center><h1>Login Failed</h1></center>\n<hr><center>nginx</center>\n</body>\n</html>\n'
                    content_type = "text/html"
                    status_line = "HTTP/1.1 401 Unauthorized"

                server_header = random.choice(self.NGINX_VERSIONS)
                resp = b"%s\r\nServer: %s\r\nDate: %s\r\nContent-Type: %s\r\nContent-Length: %d\r\nConnection: close\r\n\r\n%s" % (
                    status_line.encode(),
                    server_header.encode(),
                    datetime.now().strftime('%a, %d %b %Y %H:%M:%S GMT').encode(),
                    content_type.encode(),
                    len(body),
                    body
                )
                writer.write(resp)
                await writer.drain()

                # 记录登录尝试
                op_logger.info("Login attempt from %s: %s", peer[0], post_data.decode(errors="ignore"))
                return

            # 处理静态资源请求
            all_static_contents = {**self.STATIC_CONTENTS, **self.dynamic_paths}
            if path in all_static_contents:
                content, content_type = all_static_contents[path]

                # 记录文件访问到攻击日志
                attack_logger.log_file_access(
                    source_ip=peer[0],
                    destination_port=self.port,
                    protocol=ProtocolType.HTTP,
                    file_path=path,
                    access_type="read"
                )

                server_header = random.choice(self.NGINX_VERSIONS)
                resp = b"HTTP/1.1 200 OK\r\nServer: %s\r\nDate: %s\r\nContent-Type: %s\r\nContent-Length: %d\r\nETag: %s\r\nCache-Control: max-age=3600\r\nConnection: close\r\n\r\n%s" % (
                    server_header.encode(),
                    datetime.now().strftime('%a, %d %b %Y %H:%M:%S GMT').encode(),
                    content_type.encode(),
                    len(content),
                    self._generate_etag().encode(),
                    content
                )
                await self._simulate_network_delay(writer, len(content))
                writer.write(resp)
                await writer.drain()
                return

            # 处理/favicon.ico特殊请求
            if path == "/favicon.ico":
                content = b"\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00"

                # 记录文件访问到攻击日志
                attack_logger.log_file_access(
                    source_ip=peer[0],
                    destination_port=self.port,
                    protocol=ProtocolType.HTTP,
                    file_path=path,
                    access_type="read"
                )

                server_header = random.choice(self.NGINX_VERSIONS)
                resp = b"HTTP/1.1 200 OK\r\nServer: %s\r\nDate: %s\r\nContent-Type: image/x-icon\r\nContent-Length: %d\r\nETag: %s\r\nCache-Control: max-age=86400\r\nConnection: close\r\n\r\n%s" % (
                    server_header.encode(),
                    datetime.now().strftime('%a, %d %b %Y %H:%M:%S GMT').encode(),
                    len(content),
                    self._generate_etag().encode(),
                    content
                )
                await self._simulate_network_delay(writer, len(content))
                writer.write(resp)
                await writer.drain()
                return

            # 检查是否需要返回304
            if 'if-none-match' in headers:
                server_header = random.choice(self.NGINX_VERSIONS)
                resp = b"HTTP/1.1 304 Not Modified\r\nServer: %s\r\nDate: %s\r\nETag: %s\r\nConnection: close\r\n\r\n" % (
                    server_header.encode(),
                    datetime.now().strftime('%a, %d %b %Y %H:%M:%S GMT').encode(),
                    self._generate_etag().encode()
                )
                writer.write(resp)
                await writer.drain()
                return

            # 生成Cookie
            has_cookie = 'cookie' in headers
            session_cookie = ""
            if not has_cookie:
                session_cookie = "Set-Cookie: sessionid=%s; Path=/; HttpOnly\r\n" % self._generate_session_id()

            # 随机选择响应页面
            body = random.choice(self.RESPONSE_BODIES)

            # 随机选择nginx版本
            server_header = random.choice(self.NGINX_VERSIONS)

            # 构建响应
            resp_headers = [
                "HTTP/1.1 200 OK",
                "Server: %s" % server_header,
                "Date: %s" % datetime.now().strftime('%a, %d %b %Y %H:%M:%S GMT'),
                "Content-Type: text/html",
                "Content-Length: %d" % len(body),
                "ETag: %s" % self._generate_etag(),
                "Cache-Control: no-cache",
                "Connection: close"
            ]

            if not has_cookie:
                resp_headers.append(session_cookie.rstrip())

            resp = ("\r\n".join(resp_headers) + "\r\n\r\n").encode() + body
            await self._simulate_network_delay(writer, len(body))
            writer.write(resp)
            await writer.drain()

            entry = {
                "session_id": session_id,
                "start_time": start_ts.isoformat(),
                "end_time": datetime.now(timezone.utc).isoformat(),
                "duration_seconds": (datetime.now(timezone.utc) - start_ts).total_seconds(),
                "remote_ip": peer[0],
                "remote_port": peer[1],
                "inputs": [text],
                "raw_base64": base64.b64encode(raw).decode("ascii"),
            }
            await self.persist(entry)
        except Exception as e:
            op_logger.exception("HTTP处理器错误 %s: %s", session_id, e)
        finally:
            try:
                writer.close()
                await writer.wait_closed()
            except Exception:
                pass
            op_logger.info("HTTP关闭会话 %s 来自 %s", session_id, peer)
